﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kinect_Interface_Prototype_1.Folder_Control;
using Kinect_Interface_Prototype_1.Interface_Design;
using Kinect_Interface_Prototype_1.Mouse_Control;
using Kinect_Interface_Prototype_1.Voice_Commands;

using System.Windows.Forms;
using System.Drawing;
using Kinect_Interface_Prototype_1.Kinect_MediaPlayer;
using Kinect_Interface_Prototype_1.Gesture_Control;
using System.Threading;
using Gesture_Control.Keyboard;

namespace Kinect_Interface_Prototype_1
{
    public class StartupProgram
    {
        public static List<FolderControlForm> FolderControlForms = new List<FolderControlForm>();
        private KinectForm kinectForm;
        private ControlForm ControlForm;
        private SettingsForm SettingsForm;
        private AppDock AppDock;
        private MouseControl MouseControl;
        private GestureControl GestureControl;
        private VoiceApp voiceApp;
        private MediaPlayerForm MediaPlayer;
        public static KeyboardCover VirtualKeyboard;
       
        private ConfirmationWindow confirmationWindow;

        private IniFile configINI = new IniFile(Constants.InterfaceINI);
        private IniFile settingsINI = new IniFile(Constants.SettingsINI);

        public StartupProgram()
        {
            kinectForm = new KinectForm(this);
            ToggleShowSkeletalWindow(Boolean.Parse(settingsINI.IniReadValue("General", "showSkeletalTracking")));

            confirmationWindow = new ConfirmationWindow(this);

            ControlForm = new ControlForm(this, confirmationWindow);
            ControlForm.Show();

            voiceApp = new VoiceApp(this, confirmationWindow, Boolean.Parse(settingsINI.IniReadValue("General", "voiceCommandsStart")));
            VoiceCommands_ToggleAllVoiceCommandsState(Boolean.Parse(settingsINI.IniReadValue("Voice Control", "enabledVoiceCommands")));
            
            MouseControl = new MouseControl(this);
            GestureControl = new GestureControl(this);

            SettingsForm = new SettingsForm(this);

            AppDock = new AppDock(this, configINI, settingsINI);
            AppDock.Show();

            VirtualKeyboard = new KeyboardCover();

            
        }

        // Private Functions
        private void ToggleShowSkeletalWindow(bool show)
        {
            if (show) kinectForm.Show();
            else kinectForm.Hide();
        }

        // General Functions
        public void ShutDown()
        {
            kinectForm.ShutdownKinect();
            System.Windows.Forms.Application.Exit(); // Kills the windows forms (activating closing methods)
        }

        public void AddSystemButtons(Form form)
        {
            ImageButton closeButton = new ImageButton(Constants.SystemButtonImagesFolder, "closeButton", new Point(form.Width - 48 - 16, 0));
            closeButton.Click += delegate(object sender, EventArgs e) { form.Close(); };
            ImageButton maximizeButton = new ImageButton(Constants.SystemButtonImagesFolder, "maximizeButton", new Point(closeButton.Location.X - 28, 0));
            maximizeButton.Click += delegate(object sender, EventArgs e)
            {
                form.WindowState = form.WindowState == FormWindowState.Maximized
                                   ? FormWindowState.Normal : FormWindowState.Maximized;
            };
            ImageButton minimizeButton = new ImageButton(Constants.SystemButtonImagesFolder, "minimizeButton", new Point(maximizeButton.Location.X - 29, 0));
            minimizeButton.Click += delegate(object sender, EventArgs e) { form.WindowState = FormWindowState.Minimized; };
            form.Controls.AddRange(new Control[] { closeButton, maximizeButton, minimizeButton });
        }

        public void AddSystemButtons(Form form, ref ImageButton closeButton, ref ImageButton maximizeButton, ref ImageButton minimizeButton)
        {
            closeButton = new ImageButton(Constants.SystemButtonImagesFolder, "closeButton", new Point(form.Width - 48 - 16, 0));
            closeButton.Click += delegate(object sender, EventArgs e) { form.Close(); };
            maximizeButton = new ImageButton(Constants.SystemButtonImagesFolder, "maximizeButton", new Point(closeButton.Location.X - 28, 0));
            maximizeButton.Click += delegate(object sender, EventArgs e)
            {
                form.WindowState = form.WindowState == FormWindowState.Maximized
                                   ? FormWindowState.Normal : FormWindowState.Maximized;
            };
            minimizeButton = new ImageButton(Constants.SystemButtonImagesFolder, "minimizeButton", new Point(maximizeButton.Location.X - 29, 0));
            minimizeButton.Click += delegate(object sender, EventArgs e) { form.WindowState = FormWindowState.Minimized; };
            form.Controls.AddRange(new Control[] { closeButton, maximizeButton, minimizeButton });
        }

        #region Control Form Functions
        
        // Control Form Functions
        public void ControlForm_ResetLocation()
        {
            ControlForm.ResetLocation();
        }

        public void ControlForm_ToggleVisibility()
        {
            ControlForm_ToggleVisibility(!ControlForm.Visible);
        }

        public void ControlForm_ToggleVisibility(bool show)
        {
            if (show)
            {
                ControlForm.SetShowControlFormItemText("Hide Control Board");
                SettingsForm_SetShowControlBoardButtonText("Hide");
                ControlForm.Show();
            }
            else
            {
                ControlForm.SetShowControlFormItemText("Show Control Board");
                SettingsForm_SetShowControlBoardButtonText("Show");
                ControlForm.Hide();
            }
        }

        public void ControlForm_SwitchOff(OnOffControlType onOffControlType)
        {
            ControlForm.SwitchOff(onOffControlType);
        }

        public void ControlForm_SwitchOn(OnOffControlType onOffControlType)
        {
            ControlForm.SwitchOn(onOffControlType);
        }

        public bool ControlForm_GetSwitchOn(OnOffControlType onOffControlType)
        {
            return ControlForm.GetSwitchOn(onOffControlType);
        }

        public void ControlForm_ToggleVoiceCommandsSwitch(bool On)
        {
            if (voiceApp.Initialized)
                ControlForm.ToggleSwitch(OnOffControlType.VoiceCommands, On);
        }

        // Voice command switch is either in active or deactive state (different from on/off)
        public void ControlForm_ActivateVoiceCommandsSwitch(bool active)
        {
            ControlForm.ActivateSwitch(OnOffControlType.VoiceCommands, active);
        }

        public void ControlForm_Minimize()
        {
            ControlForm.WindowState = FormWindowState.Minimized;
        }

        public IntPtr ControlForm_Handle()
        {
            return ControlForm.Handle;
        }

        public int ControlForm_Width()
        {
            return ControlForm.Width;
        }

        #endregion

        #region Kinect Form Functions
        
        // Kinect Form Functions
        public void KinectForm_ToggleMouseControl(bool active)
        {
            kinectForm.ToggleMouseControl(active);
        }

        public void KinectForm_ToggleGestureControl(bool active)
        {
            kinectForm.ToggleGestureControl(active);
        }

        public void KinectForm_ToggleActiveGestureRectangle(GestureRectangleType type, bool active)
        {
            kinectForm.ToggleActiveGestureRectangle(type, active);
        }

        public bool KinectForm_GetVisible()
        {
            return kinectForm.Visible;
        }

        public void KinectForm_ToggleSkeletalWindowVisibility()
        {
            KinectForm_ToggleSkeletalWindowVisibility(!kinectForm.Visible);
        }

        public void KinectForm_ToggleSkeletalWindowVisibility(bool visible)
        {
            ToggleShowSkeletalWindow(visible);
            SettingsForm.showSkeletalWindowButton.Text = visible ? "Hide" : "Show";
        }

        public void KinectForm_AdjustElevation(int elevation)
        {
            kinectForm.AdjustElevation(elevation);
        }

        #endregion

        #region Mouse Control Functions
       
        // Mouse Control Functions
        public void MouseControl_UpdateMouse(float minDepth, Microsoft.Kinect.Joint rightHand, float SkeletonMaxX, float SkeletonMaxY)
        {
            MouseControl.UpdateMouse(minDepth, rightHand, SkeletonMaxX, SkeletonMaxY);
        }

        #endregion

        #region Gesture Control Functions

        public void GestureControl_DetermineGestures(bool mouseGestuesActive, bool gesturesActive, float minDepth, bool inStartGesture, bool inLeftClick, bool inDoubleClick, bool inRightClick,
                                                     bool inRightHandSwipe, HandInside handInRightHandSwipe, bool inLeftHandSwipe, HandInside handInLeftHandSwipe, bool inCenterRectangle, HandInside handInCenter,
                                                     bool inLowerLeftRectangle, HandInside HandInLowerLeftRectangle, bool inUpperRightRectangle, HandInside HandInUpperRightRectangle)
        {
            GestureControl.DetermineGestures(mouseGestuesActive, gesturesActive, minDepth, inStartGesture, inLeftClick, inDoubleClick, inRightClick,
                                             inRightHandSwipe, handInRightHandSwipe, inLeftHandSwipe, handInLeftHandSwipe, inCenterRectangle, handInCenter,
                                             inLowerLeftRectangle, HandInLowerLeftRectangle, inUpperRightRectangle, HandInUpperRightRectangle);
        }

        public void UpdateVirtualKeyboard(Microsoft.Kinect.Joint leftHand, Microsoft.Kinect.Joint rightHand)
        {
            GestureControl.UpdateVirtualKeyboard(leftHand, rightHand);
        }

        #endregion

        #region Voice App Functions

        // Voice App Functions

        // All voice commands are toggled, activate command is still active either way
        public void VoiceCommands_ToggleActive(bool active)
        {
            if (voiceApp.Initialized)
                voiceApp.VoiceCommandsActive = active;
        }

        // All voice commands are turned off, including the activate command
        public void VoiceCommands_ToggleAllVoiceCommandsState(bool on)
        {
            if (voiceApp.Initialized)
            {
                voiceApp.AllVoiceCommandsOff = !on;

                ControlForm_ActivateVoiceCommandsSwitch(on);

                // if voice commands are on, set the voice command switch to the appropriate state
                if (on)
                    ControlForm_ToggleVoiceCommandsSwitch(VoiceCommands_GetActive());
            }
        }

        public void VoiceCommands_Reset()
        {
           voiceApp.Reset();
        }

        public void VoiceCommands_SetVoiceCommandConfidence(VoiceCommandAction commandAction, double confidence)
        {
            voiceApp.SetVoiceCommandConfidence(commandAction, confidence);
        }

        // Sets a specific command to active or not
        public void VoiceCommands_SetVoiceCommandActive(VoiceCommandAction commandAction, bool active)
        {
            voiceApp.SetVoiceCommandActive(commandAction, active);
        }

        // Returns command word that does not include the command keyword
        public string VoiceCommands_GetVoiceCommandString(VoiceCommandAction commandAction)
        {
            return voiceApp.GetVoiceCommandString(commandAction);
        }

        public bool VoiceCommands_GetActive()
        {
            return voiceApp.VoiceCommandsActive;
        }

        #endregion

        #region Settings Form Functions
        
        // Settings Form Functions
        public void SettingsForm_ToggleVisibility(bool show)
        {
            if(show) SettingsForm.Show();
            else SettingsForm.Hide();
        }

        public void SettingsForm_SetShowControlBoardButtonText(string text)
        {
            SettingsForm.showControlBoardButton.Text = text;
        }

        public bool SettingsForm_GetVisible()
        {
            return SettingsForm.Visible;
        }

        #endregion

        #region App Dock Functions
        
        // App Dock Functions
        public void AppDock_ResetLocation()
        {
            AppDock.ResetLocation();
        }

        public void AppDock_ToggleVisibility()
        {
            if (AppDock.Visible)
            {
                ControlForm.SetShowAppDockItemText("Show App Dock");
                SettingsForm.showAppDockButton.Text = "Show";
                AppDock.Hide();
            }
            else
            {
                ControlForm.SetShowAppDockItemText("Hide App Dock");
                SettingsForm.showAppDockButton.Text = "Hide";
                AppDock.Show();
            }
        }

        public IntPtr AppDock_Handle()
        {
            return AppDock.Handle;
        }

        public bool AppDock_getVisibility()
        {
            if (AppDock.Visible)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public void AppDock_Refresh()
        {
            AppDock.RefreshAppDock();
        }

        public void AppDock_Minimize()
        {
            AppDock.WindowState = FormWindowState.Minimized;
        }
        
        public void AppDock_AppClick(int appNumber)
        {
            AppDock.AppClick(appNumber);
        }

        #endregion

        #region Folder Control Form Functions

        /*
        public Boolean folderFormVisible()
        {
            if (FolderControlForm.ActiveForm.Visible.Equals(true))
            {
                return true;
            }
            else { return false; }
        }
         */

        #endregion

        #region Media Player Functions

        public bool MediaPlayer_IsOpen()
        {
            return MediaPlayer != null;
        }

        public void MediaPlayer_Open()
        {
            if (MediaPlayer == null)
                MediaPlayer = new MediaPlayerForm(this);

            if(MediaPlayer.IsDisposed)
                MediaPlayer = new MediaPlayerForm(this);

            MediaPlayer.Show();
        } 

        public void MediaPlayer_Dispose()
        {
            MediaPlayer = null;
        }

        public IntPtr MediaPlayer_Handle()
        {
            return MediaPlayer.Handle;
        }

        public void MediaPlayer_NextLibraryPage()
        {
            if (MediaPlayer.State == MediaPlayerForm.MediaPlayerState.Library)
                MediaPlayer.NextLibaryPage();
        }

        public void MediaPlayer_PreviousLibraryPage()
        {
            if (MediaPlayer.State == MediaPlayerForm.MediaPlayerState.Library)
                MediaPlayer.PreviousLibaryPage();
        }

        #endregion

        #region Virtual Keyboard

        public bool VirtualKeyboard_IsKeyboardUp()
        {
            return Gesture_Control.GestureControl.isKeyboardUp == 1;
        }

        public void VirtualKeyboard_Show()
        {
            VirtualKeyboard.ShowKeyboard();
            Gesture_Control.GestureControl.isKeyboardUp = 1;
        }

        public void VirtualKeyboard_Hide()
        {
            VirtualKeyboard.HideKeyboard();
            Gesture_Control.GestureControl.isKeyboardUp = 0;
        }

        public IntPtr VirtualKeyboard_Handle()
        {
            return VirtualKeyboard.Handle;
        }

        #endregion

        
    }
}
